export class LinkedList {
  length: number = 0
  head: any = null
  constructor() {}
  //获取某个位置的值
  get(position: number) {
    if (position < 0 || position >= this.length) return null
    var current = this.head
    for (var i = 0; i < position; i++) {
      current = current.next
    }
    return current.data
  }
  //获取某个位置的节点
  getNode(position: number) {
    if (position < 0 || position >= this.length) return null
    var current = this.head
    for (var i = 0; i < position; i++) {
      current = current.next
    }
    return current
  }
  //更新某个位置的值
  update(position: number, data: any) {
    if (position < 0 || position >= this.length) return null
    var current = this.head
    for (var i = 0; i < position; i++) {
      current = current.next
    }
    current.data = data
  }
  //向列表尾部添加一个新的元素
  append(data: any, engData?: any) {
    var node = new LinkNode(data + ' ') //构造新的元素节点
    if (engData) {
      node.engData = engData + ' '
    }
    var current
    if (this.head === null) {
      //头节点为空时  当前结点作为头节点
      this.head = node
    } else {
      current = this.head
      while (current.next) {
        //遍历，直到节点的next为null时停止循环，当前节点为尾节点
        current = current.next
      }
      current.next = node //将尾节点指向新的元素，新元素作为尾节点
    }
    this.length++ //更新链表长度
  }
  //从列表的移除一个或一段节点,并返回光标应该在的node位置
  removeAt(position: number, endPosition?: number) {
    /**
     * position:在链中的位置（若是一段选中，就是这段选中的前面位置）
     * endPosition：在链中的位置（一段选中的后面位置）
     */
    if (position > -1 && position < this.length) {
      var current = this.head
      var index = 0
      var previous: any = null
      let focusPosition = 0
      if (position == 0 && !endPosition) {
        //指定删除0位置的节点
        this.head = current?.next || null
        focusPosition = -1 //光标在最前面
      } else {
        while (index++ < position) {
          previous = current
          current = current.next
          focusPosition = index - 1
        }
        if (endPosition) {
          let aftNode = this.getNode(endPosition)
          if (!previous) {
            //说明所有节点全删完了
            this.head = aftNode.next
          } else {
            previous.next = aftNode.next
          }
          this.length = this.length - (endPosition - position + 1)
        } else {
          previous.next = current.next
          this.length--
        }
      }
      return focusPosition
    } else if (position >= this.length) {
      return this.length
    } else {
      return 0
    }
  }
  //在某个位置中插入一个元素。
  insert(position: number, data: any, engData?: any, datatype?: any) {
    if (position > -1 && position <= this.length) {
      //校验边界
      var node = new LinkNode(data + ' ')
      if (engData) {
        node.engData = engData + ' '
      }
      if (datatype) {
        node.type = datatype
      }
      var current = this.head
      var index = 0
      var previous
      if (position == 0) {
        //作为头节点，将新节点的next指向原有的头节点。
        if (node.type && node.type == current?.type) {
          //相邻类型一样不能输入
          return false
        }
        node.next = current
        this.head = node //新节点赋值给头节点
      } else {
        while (index++ < position) {
          previous = current
          current = current.next
        } //遍历结束得到当前position所在的current节点，和上一个节点
        if (
          node.type &&
          (node.type == previous.type || node.type == current?.type)
        ) {
          return false
        }
        previous.next = node //上一个节点的next指向新节点  新节点指向当前结点，可以参照上图来看
        node.next = current
      }
      this.length++
      return true
    } else {
      return false
    }
  }
  insertAtFocus(focusIndex: any, data: any, engData?: any, datatype?: any) {
    let currstr = this.toString()
    if (!currstr) {
      //没有一个节点的链表
      this.append(data, engData)
      return true
    }
    if (focusIndex == 0) {
      //在0位置直接插入
      return this.insert(0, data, engData, datatype)
    }
    //焦点当前或者焦点前一个位置都可以插入
    let preNumb = focusIndex - 1
    let chart = currstr.charAt(focusIndex)
    let preChart = currstr.charAt(preNumb)
    let position = -1
    if (preChart == ' ' || preChart == undefined) {
      //前面位置符合插入条件，就在当前位置插入
      position = this.byFocusGetNodeInfo(focusIndex).position
    } else if (chart == ' ' || chart == undefined) {
      //后面位置符合插入条件，就在当前位置+1插入
      position = this.byFocusGetNodeInfo(focusIndex).position + 1
    }
    // let slicestr = currstr.slice(0, focusIndex)
    // let arr = slicestr.split(" ")

    // for (let i = 0, len = arr.length; i < len; i++) {
    //     if (arr[i] == " " || arr[i] == "") {
    //         arr.splice(i, 1)
    //     }
    // }
    return this.insert(position, data, engData, datatype)
    //  return this.insert(arr.length, data, engData, datatype)
  }
  removeAtFocus(startFocus: any, endFocus: any, key: any) {
    let currstr = this.toString()
    //删除光标在的位置的node
    let focusPosition = -1
    if (startFocus == endFocus) {
      focusPosition = this.byFocusGetNodeInfo(startFocus).position
      let chart = currstr.charAt(startFocus)
      let chartPre = currstr.charAt(startFocus - 1)
      if (chartPre == ' ' || chartPre == undefined) {
        //q b 5 |h，鼠标在h前，回车删除的是5
        if (key == 'backspace') {
          focusPosition = this.removeAt(focusPosition - 1)
          return focusPosition
        }
      }
      if (chart == ' ' || chart == undefined) {
        //q b 5| h，鼠标在5后前，delete删除的是h
        if (key == 'delete') {
          focusPosition = this.removeAt(focusPosition + 1)
          return focusPosition
        }
      }

      focusPosition = this.removeAt(focusPosition)

      // let currstr = this.toString()
      // let slicestr = currstr.slice(0, startFocus)
      // let arr = slicestr.split(" ")
      // for (let i = 0, len = arr.length; i < len; i++) {
      //     if (arr[i] == " " || arr[i] == "") {
      //         arr.splice(i, 1)
      //     }
      // }
      // let len = arr.length
      // if (len > 0) {//len=0说明是在删除第一个node
      //     if (this.get(len - 1)?.length > (arr[len - 1]?.toString())?.length) {
      //         focusPosition = this.removeAt(arr.length - 1)
      //     } else if (key == 'delete') {
      //         focusPosition = this.removeAt(arr.length)
      //     } else if (key == 'backspace') {
      //         focusPosition = this.removeAt(arr.length - 1)
      //     }
      // } else if (len == 0) {
      //     if (key == 'delete') {
      //         focusPosition = this.removeAt(0)
      //     }
      // }
    } else {
      let start = this.byFocusGetNodeInfo(startFocus + 1).position
      let end = this.byFocusGetNodeInfo(endFocus - 1).position
      if (start == end) {
        //选中的是一个节点的一段
        focusPosition = this.removeAt(start)
      } else {
        //选中的是多个节点
        focusPosition = this.removeAt(start, end)
      }

      // let currstr = this.toString()
      // //选中整块全删
      // let defStart = currstr.slice(0, startFocus)
      // let defEnd = currstr.slice(0, endFocus)
      // let arr1 = defStart.split(" ")
      // let arr2 = defEnd.split(" ")
      // for (let i = 0, len = arr1.length; i < len; i++) {
      //     if (arr1[i] == " " || arr1[i] == "") {
      //         arr1.splice(i, 1)
      //     }
      // }
      // for (let i = 0, len = arr2.length; i < len; i++) {
      //     if (arr2[i] == " " || arr2[i] == "") {
      //         arr2.splice(i, 1)
      //     }
      // }
      // focusPosition = startFocus
      // focusPosition = this.removeAt(arr1.length - 1, arr2.length)
    }
    return focusPosition //返回光标位置
  }
  //返回元素在列表中的索引。如果没有该元素则返回-1
  indexOf(data: any) {
    var current = this.head
    var index = -1
    while (current) {
      if (data + ' ' === current.data) {
        //从头节点开始遍历
        return index
      }
      index++
      current = current.next
    }
    return -1
  }
  //转成字符串
  toString() {
    var current = this.head
    var string = ''
    while (current) {
      string += current.data
      current = current.next
    }
    return string
  }
  //转纯英文字符串
  toEngString() {
    var current = this.head
    var string = ''
    while (current) {
      if (current.engData) {
        string += current.engData
      } else string += current.data
      current = current.next
    }
    return string
  }
  toRuleField() {
    var current = this.head
    var fileds: any = []
    while (current) {
      let start = current?.engData?.indexOf('{') || -1
      let end = current?.engData?.indexOf('}') || -1
      if (start != -1) {
        let field = current.engData.slice(start + 1, end)
        let obj: any = {
          field: field,
          type:
            field != 'deviceTypeKey' && field != 'deviceName'
              ? 'POINT'
              : 'BASE',
        }
        fileds = fileds.filter(
          (item: { field: any }) => item.field != obj.field,
        )
        fileds.push(obj)
      }
      current = current.next
    }
    return fileds
  }
  parse(str: any, engStr: any) {
    //字符串转链表
    if (str && engStr) {
      this.head = null
      this.length = 0
      let arr = str.split(' ')
      let arrEng = engStr.split(' ')
      for (let i = 0, len = arr.length; i < len; i++) {
        if (arr[i]) {
          //有值执行追加，' '不追加
          this.append(arr[i], arrEng[i])
        }
      }
    }
  }
  toPositionString(position: any) {
    var string = ''
    //if (position < 0 || position >= this.length) return null;
    var current = this.head
    if (position == -1) {
      return string
    }
    for (var i = 0; i <= position; i++) {
      if (current) {
        string += current?.data
        current = current?.next
      }
    }
    return string
  }
  //长度
  size() {
    return this.length
  }
  byFocusGetNodeInfo(fIndex: any) {
    //根据焦点位置获得属于哪个节点以及节点在链表的位置
    let current = this.head
    let position = 0
    if (current) {
      let str = current.data
      while (str.length <= fIndex) {
        if (current) {
          current = current?.next
          position++
          if (current?.data) {
            str += current?.data
          }
        } else {
          str = str + fIndex
        }
      }
    }

    return { current, position }
  }
}
class LinkNode {
  //新元素构造
  //非正常链表data，值和额外信息
  data: any
  engData: any = null
  type: any = null
  next: any = null
  constructor(data: any) {
    this.data = data
  }
}
